#pragma once
#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#include<functional>

typedef std::function<void*(void*)> thread_func;

namespace ly{
    template<class T>
    class pthread{
        private:
            static void *run(void *arg){//去除this·指针
                pthread* This=(pthread*)arg;
                return This->_func(&This->_data);
            }
        public:
            pthread(thread_func f,T data=T()):_func(f),_is_running(false),_tid(0),_data(data)
                , _joinreval(NULL),_is_detached(false),_is_jioned(false)
            {}
            ~pthread(){}
            void start(T data=T()){
                if(_is_running) return;
                _is_running=true;
                if(data) _data=data;
                pthread_create(&_tid,NULL,run,this);
            }
            void* join(){
                if(!_is_running) return NULL;
                if(_is_jioned) return _joinreval;
                if(_is_detached){
                    return NULL;
                }
                pthread_join(_tid,&_joinreval);
                _is_running=false;
                _is_jioned=true;
                _is_detached=false;
                return _joinreval;
            }
            void detach(){
                if(_is_detached) return;
                pthread_detach(_tid);
                _is_detached=true;
            }
            void exit(){
                pthread_cancel(_tid);
            }
            bool is_running(){return _is_running;}
            bool is_detached(){return _is_detached;}
            bool is_jioned(){return _is_jioned;}
            pthread_t get_tid(){
                if(_is_detached||_is_jioned)
                    return 0;
                return _tid;
            }
            void* get_jionreval(){
                if(_is_detached) return NULL;
                if(!_is_jioned) return NULL;
                return _joinreval;
            }
        private:
            bool _is_running,_is_detached,_is_jioned;
            pthread_t _tid;
            thread_func _func;
            T _data;
            void* _joinreval;
    };
}
